— 2 min read
장장 564p.나 되는 '쏙쏙 들어오는 함수형 코딩(에릭 노먼드 저)'책의 1회독을 끝냈다. 함께 스터디한 팀원들이 없었다면 정말 쉽지 않았을 여정. 그리고 이 책은 정말 친절하다. 함수형 코딩이라는 개념을 처음 접하는 사람들을 대상으로 쓰여진 책이고 중간중간 나오는 연습문제와 챕터 마지막의 결론, 다음 챕터에서의 반복 등으로 어렵지않게 학습할 수 있다. 우리 스터디에서는 연습문제를 스터디 시간에 같이 풀고 토론했는데 그 시간이 더 이해를 높이는데 도움이 되었던 것 같다.
책의 예제는 자바스크립트로 되어있지만, 저자는 이 책이 자바스크립트 책이 아니라고 재차 강조한다. 아마 다른 함수형 언어를 안다면 책을 잘 따라갈 수 있을 듯 하다.
책을 읽기 전까지 나의 나이브한 생각은 ‘부수효과를 만들지 않는 순수함수로 프로그래밍하는 패러다임 ?.?’ 정도였다. 위키피디아의 정의도 거의 비슷하다 : 수학함수를 사용하고 부수효과를 피하는 것이 특징인 프로그래밍 패러다임
그러나!! 저자는 일반적인 FP의 정의대로라면 이메일 전송도 하지 못할것이라고 지적하며, 부수효과를 아얘 만들지 않는게 아니라 잘 다룰 수 있는게 FP라고 말한다.
책에서 다루는 함수형 사고의 가장 중요한 두가지 개념은 액션과 계산, 데이터를 구분해서 생각하는 것
, 그리고 일급추상
이다.
액션, 계산, 데이터를 구분하고 더 좋은 코드를 위해서는 최대한 액션에서 계산을 분리하고 계산에서 데이터를 분리 해야한다.
액션, 계산, 데이터를 구분하는 것이 왜 중요한가?
1// 계산 구분 전2var subscribers = ["myang", "soo", "sh"]3function sendMessagesToSubscribers() {4 for (var i = 0; i < subscribers.length; i++) {5 if (getCouponRank(subscribers[i]) == "A") {6 var message = {7 title: "title for A grade customers" 8 body: "You got a best deal: ~~"9 }; // message 객체는 데이터다.10 sendMessage(message);11 } else {12 var message = {13 title: "title for B grade customers" 14 body: "You got a bad deal: ~~"15 };16 sendMessage(message);17 }18 }19}2021// 계산 구분 후22function sendMessagesToSubscribers(subscribers) {23 var messages = messagesForSubscribers(subscribers);24 for (var i = 0; i < subscribers.length; i++) {25 sendMessage(message[i]);26 }27}2829function messagesForSubscribers(subscribers) { // 계산30 return subscribers.map(subscribers, function(subscriber) {31 return messageForSubscriber(subscriber);32 });33}3435function messageForSubscriber(subscriber) {36 if (getCouponRank(subscribers[i]) == "A") {37 return {38 title: "title for A grade customers" 39 body: "You got a best deal: ~~"40 };41 } else {42 return {43 title: "title for B grade customers" 44 body: "You got a bad deal: ~~"45 };46 }47}
어떻게 액션을 계산으로 만들 수 있나
함수에 암묵적 입력(ex. 전역변수를 읽는 것)과 암묵적 출력(ex. console.log)이 있으면 액션.
암묵적 입력은 parameter로, 암묵적 출력은 return 값으로 나타내면 계산이 된다.
이 암묵적 입출력을 없애는 과정에서 불변성 구현이 필요하다.
변경 가능한 데이터를 읽는 것은 액션(읽을 때마다 다른 값을 읽을 수 있으므로)이지만, 불변 데이터 구조를 읽는 것은 계산이 된다.
Haskell, Clojure 등의 함수형 프로그래밍 언어는 언어 자체에서 불변성을 구현하고 있다. 그러나 자바스크립트는 직접 구현해야한다.
불변성을 유지하기 위해 적용 가능한 원칙 1) copy-on-write: 어떤 값의 복사본을 만들고, 직접 값을 바꾸지 않는 것.
1// 인자로 전달한 배열을 직접 변경하는 것은 액션이다. (배열이 바뀌는 부수효과가 발생)23var cart = [...] // 전역변수4remove_item_by_name(cart, 'rubber_duck');56function remove_item_by_name(cart, name) {7 var idx = null;8 for(var i = 0; i < cart.length; i++) {9 if(cart[i].name === name) {10 idx = i;11 }12 if (idx !== null) {13 cart.splice(idx, 1); // 전역변수를 수정14 }15}
1// copy-on-write 적용하여 계산으로 바꾸기23function remove_item_by_name(cart, name) {4 var new_cart = cart.slice(); // 1. 복사본 만들기5 for(var i = 0; i < new_cart.length; i++) {6 if(new_cart[i].name === name) {7 idx = i;8 }9 if (idx !== null) {10 new_cart.splice(idx, 1); // 2. 복사본 변경하기11 }12 return new_cart; // 3. 복사본 리턴하기13}
불변성을 유지하기 위해 적용 가능한 원칙 2) 방어적 복사: 불변성이 지켜지는 안전지대의 바깥으로 들어오고 나가는 데이터의 복사본을 만들기
1- 바꿀 수 없는 레거시 코드 또는 라이브러리의 함수를 사용해야할 때, 안전지대 바깥과 상호작용 하게 된다. 2- 이 때 deep copy로 nested data를 복사해야함3- deep copy는 비용이 많이 듬. 안전지대 안에서는 copy-on-write로 충분하다.45```javascript6function black_friday_promotion(cart) {7 // 통제 바깥의 코드. 무슨 일이 일어나는지 알 수 없음. cart를 변경할 수도 있음8}910function add_item_to_cart(name, price) {11 // ...12 var cart_copy = deepCopy(cart); // 데이터가 안전지대에서 나갈 때 복사13 black_friday_promotion(cart_copy);14 cart = deepCopy(cart_copy); // 안전지대로 데이터가 들어올 때 복사15}16```
** 이렇게 코드짤때마다 신경쓰면서 일일이 다 copy를 해야할까? 에 대한 대안은 immutable.js 같은 라이브러리 사용이 아닐까 싶다. 코틀린의 경우 immutable collection을 쓰는것
blablaFunction(a)(b)
같은 문법이 가능하다. blablaFunction(a)
의 결과가 또 함수이기 때문에 blablaReturnFunction(b)
가 되어서 실행되는 식..1// 리팩토링 전2function calc_total(cart) {3 // ...4 update_total_dom(total);5}67// 리팩토링 후8function calc_total(cart, callback) {9 // ...10 callback(total);11}
단순히 누산하는데에만 쓰이지 않고, 여러 쓰임새가 있다.
⇒ 이벤트 소싱과 비슷한 개념.
filter, map도 결국 reduce로 만들 수 있다.
1function filter(array, f) {2 return reduce(array, [], function(ret, item) {3 if (f(item)) {4 ret.push(item);5 }6 return ret;7 });8}
위의 개념들 외에도 타임라인 커팅, 계층형 설계, 동시성을 다루는 부분들도 나오는데 다 담지는 못하겠다…. 동시성 관련은 조금더 공부해서 따로 글을 써보고 싶다.
입문서라 길게 공부했음에도 이 책만으로 함수형 프로그래밍은 맛보기만 한 기분이다. 다음 책은 무엇으로..?